package cn.talk.doodle.ability.base;

import ohos.app.AbilityContext;
import ohos.app.Context;
import ohos.app.dispatcher.task.TaskPriority;

public abstract class AsyncTask<Params, Integer, Result> {

    private final Context context;

    public AsyncTask(Context context) {
        this.context = context;
    }

    public final Context getAbilityContext(){
        return context;
    }

    protected void onPreExecute() {
    }

    protected abstract Result doInBackground(Params... params);

    protected void onProgressUpdate(Integer... progresses) {
    }

    protected void onPostExecute(Result result) {
    }

    protected void publishProgress(Integer... progresses) {
        runUIThread(() -> onProgressUpdate(progresses));
    }

    public void execute(Params... params) {
        runUIThread(this::onPreExecute);
        runWorkerThread(new WorkerRunnable<Params, Result>(params));
    }

    private void runUIThread(Runnable runnable) {
        if (context != null) {
            context.getUITaskDispatcher().delayDispatch(runnable, 1);
        }
    }

    private void runWorkerThread(Runnable runnable) {
        if (context != null) {
            context.getGlobalTaskDispatcher(TaskPriority.HIGH).delayDispatch(runnable, 1000);
        }
    }

    private class WorkerRunnable<P extends Params, R extends Result> implements Runnable {

        private final P[] params;

        public WorkerRunnable(P[] params) {
            this.params = params;
        }

        @Override
        public void run() {
            Result result = doInBackground(params);
            runUIThread(() -> onPostExecute(result));
        }
    }

}
